/*
** Sound device interface and helpers
*/

#ifndef _SOUND_DEVICE_H
#define _SOUND_DEVICE_H

// Sets panning on all of the device channels
#define PAN_ALL_CHANNELS -1

typedef struct {
	const char* type;			// Type of device, usually the model number (such as YM2151).
	const char* description;	// What the device is, usually something like "Yamaha OPN2" or "8-channel PCM chip"
	const char* manufacturer;	// Who dunnit.
	const char* sourcefile;		// Source file responsible for this sound device driver.
} DeviceInfo;

class CBaseSoundDevice;


/***********************************************
			SMSE2K Interfaces
***********************************************/

// Sound device callbacks for stuff that needs it. Usually used for implementing timers or custom reads / writes
class ISoundDeviceCallbacks {
	public:
		virtual void SndInterrupt(CBaseSoundDevice* dev, int status) {}
		virtual void SndTimerUpdate(CBaseSoundDevice* dev, int parameter) {}
		virtual int  SndReadPort(CBaseSoundDevice * dev, int port) { return 0; }
		virtual void SndWritePort(CBaseSoundDevice * dev, int port, int data) {}
};

// Current sound interface version.
#define SOUND_INTERFACE_CURRENT_VERSION   1


// Sound Device Interface. If we need to change a bunch of shit that breaks the code, we use an interface to do stuff.
// This is interface version 1.
class ISoundDevice {
	public: // Basic sound device calls. These pretty much do a direct call off to the functions...
		virtual void Init(CMixer* mixer, unsigned int clock) = 0;
		virtual void Shutdown() = 0;
		virtual void Reset() = 0;
		virtual int Buffer(short** buffers, int length) = 0; // Generates audio in buf
		virtual void Write(UINT64 addr, UINT8 data) = 0; // Write data to the device
		virtual UINT8 Read(UINT64 addr) = 0; // Read something from the device
		virtual const char* GetName() = 0; // Device name
		virtual int GetRomSlotCount() = 0; // Amount of ROMs this device supports
		virtual void SetRom(int slot, CMemory* rom) = 0; 
		virtual void SetCallbacks(ISoundDeviceCallbacks* callbackinterface) = 0;

		// Device information stuff
		virtual DeviceInfo* GetDeviceInformation() = 0; // Returns device info.
		virtual void SetDeviceName(const char* name) = 0;			// Change the device's name.

		// Mixer-only calls
		virtual int GetOutputCount() = 0; // Returns 1 (mono) or 2 (stereo). Unlike MAME, filters are done through devices
		virtual int GetChannelsCount() = 0;
		virtual int GetChannelFrequency(int ch) = 0;
		virtual void MuteChannel(int ch) = 0;
		virtual char GetPan(int ch) = 0;
		virtual void SetPan(int ch, char position, UINT8 invert) = 0;
};


class CBaseSoundDevice : public ISoundDevice {
	protected:
		ISoundDeviceCallbacks* callbacks;
		int samplerate_output; // The sampling rate of the audio we're generating
		int samplerate_native; // The sampling rate the chip is running at
		UINT32 clock;

		int logical_channels;
		int output_channels;

		const char* devname; // Name of this device to address through memory management (ym, oki, etc.)
	private: // Stuff


	public: // Functions that may not be required by the sound device.
		virtual int GetRomSlotCount() { return 0; } // Amount of ROMs this device supports
		virtual void SetRom(int slot, CMemory* rom) {  };
		virtual void Shutdown() { };
		
	public: // Optional stuff to override
		virtual const char* GetName() { return devname; } // Device name
		virtual DeviceInfo* GetDeviceInformation() { return NULL; } // Returns device info.
		virtual void SetCallbacks(ISoundDeviceCallbacks* callbackinterface) { callbacks = callbackinterface; }

		virtual int GetNativeSampleRate() { return samplerate_native; }
		
		virtual void SetDeviceName(const char* name) { devname = name; }			// Change the device's name.
		virtual int GetOutputCount() { return 0; }  // Returns 1 (mono) or 2 (stereo). Unlike MAME, filters are done through devices
		virtual int GetChannelsCount() { return 0; } // Get amount of logical channels this device has.
		virtual int GetChannelFrequency(int ch) { return 0; } // Get the frequency of a certain channel.
		virtual void MuteChannel(int ch) { return; } // Mute a channel.
		virtual char GetPan(int ch) { return 0; }  // 
		virtual void SetPan(int ch, char position, UINT8 invert) { }
};


#endif